home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus Special 23
/
AMIGAplus Sonderheft 23 (2000)(Falke)(DE)[!].iso
/
PublicDomain
/
Anwendungen
/
db3.6-beta-src
/
DESIGN.C
< prev
next >
Wrap
C/C++ Source or Header
|
1997-11-25
|
52KB
|
1,512 lines
#include <exec/types.h>
#include <intuition/intuition.h>
#include <libraries/gadtools.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/gadtools.h>
#include <proto/utility.h>
#include <proto/exec.h> /* CopyMem() */
#include <string.h> /* strcpy */
#include <stdlib.h> /* abs() macro */
#include "Design.h"
#include "dbGUI.h"
#include "dbparser.h"
#include "Toolbox.h"
#include "DesignGUI.h"
#include "Version.h"
#include "Pointers.h"
#include <stdio.h> // Diagnostics
/*
* Externs to make the new GadToolsBox interface work
* Remove "static" from these in DesignGUI.c
*/
extern struct Gadget *VisGadgets[];
extern struct Window *VisWnd;
extern struct NewMenu DesignNewMenu[];
extern struct Menu *DesignMenus;
#define CURSORWIDTH 3
#define DRAGTRESHOLD 6
#define TOGGLE_LED *(UBYTE *)0xbfe001 ^= 2 /* Debug */
/* Handy macros */
#define FLOOR(x,f) if ((x)<(f)) (x) = (f)
/* Return codes from GadToolBox handlers */
#define RET_OK 1
#define RET_CANCEL 2
extern WORD LastLeftEdge;
extern WORD LastTopEdge; /* For nice layoutswitching */
extern void UpdateWindow(struct Pro *Pr);
extern void UpdateDragBar(struct Pro *Pr);
typedef int Bool; /* A char would be smaller, but will produce non-cast warnings */
typedef struct {
struct VisFldInfo *vf;
Bool after; /* Has cursor passed field? (to the left or right of field) */
} Cursor;
struct EasyStruct ES_ViewDesignHelp =
{
sizeof(struct EasyStruct),
0,
(STRPTR)"View design",
(STRPTR)"%s",
(STRPTR)"Ok"
};
/**********************************************************************/
/* Globals */
/**********************************************************************/
Cursor Crsr;
struct VisFldInfo *Selected; /* The selected field that has a rubberband */
int DragCnt = 0; /* Non-zero if dragging Selected. */
Bool Sizing = FALSE;
struct Window *ToolBox = NULL;
/* GadToolBox handlers uses global variables */
extern struct Pro *CurrentPro;
struct VisFldInfo *Vf;
extern char *RFFTagNames[];
/* The clipboard */
struct VisFldInfo *Clip = NULL;
/**********************************************************************/
/* Support functions */
/**********************************************************************/
struct VisFldInfo *PrevVisFldInfo(struct Layout *Lay, struct VisFldInfo *vf)
{
struct VisFldInfo *t = Lay->FirstVisFldInfo;
if (t == vf) return NULL;
for (; t; t = t->Next) if (t->Next == vf) return t;
return NULL; /* Safety */
}
static void InitCursor(struct Layout *Lay, Cursor *crsr)
{
crsr->vf = Lay->FirstVisFldInfo;
crsr->after = FALSE;
}
static void GetCursorPosition(Cursor *crsr, WORD *x, WORD *y)
{
/* Return position of cursor in (x,y) coords */
if (crsr->vf) {
*y = crsr->vf->Pos.YOffset;
*x = crsr->vf->Pos.XOffset;
*x += (crsr->after) ? crsr->vf->Pos.Width + CURSORWIDTH : -2*CURSORWIDTH;
}
else {
*x = OffX + FontX; /* As in CalcAllPos() */
*y = OffY + (FontY >> 1); /* As in CalcAllPos() */
}
}
static int PreviousPosition(struct Layout *Lay, Cursor *crsr)
{
/* Position cursor one step to the left (maybe up) */
/* Return FALSE if this is not possible */
struct VisFldInfo *vf;
if (!crsr->vf) return FALSE; /* No gadgets at all */
if (crsr->after) {
crsr->after = FALSE;
return TRUE;
}
else if (vf = PrevVisFldInfo(Lay, crsr->vf)) {
crsr->vf = vf;
crsr->after = TRUE;
return TRUE;
}
return FALSE;
}
static int NextPosition(struct Layout *Lay, Cursor *crsr)
{
/* Position cursor one step to the right (maybe down) */
/* Return FALSE if this is not possible */
if (!crsr->vf) return FALSE; /* No gadgets at all */
if (!crsr->after) {
crsr->after = TRUE;
return TRUE;
}
else if (crsr->vf->Next) {
crsr->vf = crsr->vf->Next;
crsr->after = FALSE;
return TRUE;
}
return FALSE;
}
static void DisplayCursor(struct RastPort *rp, WORD x, WORD y)
{
/* Draws a cursor in complement colour at given position */
/* Deletes cursor at old position automatically */
/* Specify a negative coordinate in either x or y to remove cursor */
/* DisplayCursor assumes a locked cursorheight */
static WORD oldx = -1, oldy = -1;
SetDrMd(rp, COMPLEMENT);
if (oldx>=0 && oldy>=0)
RectFill(rp, oldx, oldy, oldx+CURSORWIDTH-1, oldy+FontY+STRGADFRAMESHEIGHT-1);
if (x>=0 && y>=0)
RectFill(rp, x, y, x+CURSORWIDTH-1, y+FontY+STRGADFRAMESHEIGHT-1);
oldx = x;
oldy = y;
}
static void Rubberband(struct RastPort *rp, WORD left, WORD top, WORD width, WORD height, char handle)
{
/* Draws a border rectangle in complement colour. Adds a handle square if "handle" is TRUE */
/* Deletes old rubberband automatically */
/* Specify a negative coordinate in either left or top to remove rubberband */
static WORD oldleft = -1, oldtop = -1, oldwidth=-1, oldheight=-1, oldhandle = 0;
SetDrMd(rp, COMPLEMENT);
left--; top--; width++; height++;
if (oldleft>=0 && oldtop>=0) {
Move(rp, oldleft, oldtop);
Draw(rp, oldleft+oldwidth, oldtop);
Draw(rp, oldleft+oldwidth, oldtop+oldheight);
Draw(rp, oldleft, oldtop+oldheight);
Draw(rp, oldleft, oldtop);
if (oldhandle) { /* Draw a 3x4 square in the middle of the right border */
RectFill(rp, oldleft+oldwidth+1, oldtop+(oldheight>>1), oldleft+oldwidth+4, oldtop+(oldheight>>1)+2);
}
}
if (left>=0 && top>=0) {
Move(rp, left, top);
Draw(rp, left+width, top);
Draw(rp, left+width, top+height);
Draw(rp, left, top+height);
Draw(rp, left, top);
if (handle) { /* Draw a 3x4 square in the middle of the right border */
RectFill(rp, left+width+1, top+(height>>1), left+width+4, top+(height>>1)+2);
}
}
oldleft = left; oldtop = top; oldwidth = width; oldheight = height; oldhandle = handle;
}
void FollowMouse(struct Layout *Lay, WORD mx, WORD my)
{
/* Moves the cursor to the position that is nearest to (x,y) */
Cursor nearest;
WORD x,y;
WORD nx, ny;
if (!Crsr.vf) return;
while (PreviousPosition(Lay, &Crsr)); /* Go to the beginning */
nearest = Crsr;
GetCursorPosition(&nearest, &nx, &ny);
while (NextPosition(Lay, &Crsr)) {
GetCursorPosition(&Crsr, &x, &y);
if (abs(my-y) < abs(my-ny)) {
nearest = Crsr;
GetCursorPosition(&nearest, &nx, &ny);
}
if (abs(my-y) == abs(my-ny))
if (abs(mx-x) < abs(mx-nx)) {
nearest = Crsr;
GetCursorPosition(&nearest, &nx, &ny);
}
}
Crsr = nearest;
DisplayCursor(Lay->Window->RPort, nx, ny);
}
static struct VisFldInfo *VisFldHit(struct Layout *Lay, WORD x, WORD y)
{
/* Returns the address of the VisFldInfo that is hit by (x,y) */
struct VisFldInfo *vf = NULL;
for (vf = Lay->FirstVisFldInfo; vf; vf = vf->Next) {
if (x >= vf->Pos.XOffset && x < vf->Pos.XOffset+vf->Pos.Width &&
y >= vf->Pos.YOffset && y < vf->Pos.YOffset+vf->Pos.Height)